package com.prs.crm.dao.flow.impl;

import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.prs.crm.dao.flow.WorkFlowInstanceDao;
import com.prs.crm.dao.impl.BaseDaoImpl;
import com.prs.crm.domain.flow.WorkFlow;
import com.prs.crm.domain.flow.WorkFlowInstance;
import com.prs.crm.domain.flow.WorkFlowInstanceNode;
import com.prs.crm.domain.flow.WorkFlowType;
import com.prs.crm.domain.sys.Form;

public class WorkFlowInstanceDaoImpl extends BaseDaoImpl<WorkFlowInstance>
	implements WorkFlowInstanceDao{
	
	public 	void saveNode(WorkFlowInstanceNode node)
	{
		this.getHibernateTemplate().save(node);
	}
	
	@SuppressWarnings("unchecked")
	public 	Collection<WorkFlowInstance> findFormInstance(final Form form,final WorkFlowType type ,final Integer state)
	{
		return (Collection<WorkFlowInstance> )getHibernateTemplate().execute(   
			      new HibernateCallback() {   
					public Object doInHibernate(Session session) throws HibernateException {   
			        	Criteria criteria =  session.createCriteria(WorkFlowInstance.class);
			        	if (state!=null)
			        		criteria.add(Restrictions.eq("state", state));
			        	if (type!=null)
			        		criteria.add(Restrictions.eq("type", type));
			        	criteria.add(Restrictions.eq("form", form))
			        		.addOrder(Order.asc("id"));
			        	return criteria.list();
			        
			        }   
			      }   
			    );  
	}
	
  public WorkFlowInstance findEnforeInstance(final Form form)
  {
		return (WorkFlowInstance)getHibernateTemplate().execute(   
			      new HibernateCallback() {   
					@SuppressWarnings("unchecked")
					public Object doInHibernate(Session session) throws HibernateException {   
			        	Criteria criteria =  session.createCriteria(WorkFlowInstance.class);
			        	criteria.add(Restrictions.eq("form", form))
		        						.add(Restrictions.eq("enforcement", Boolean.TRUE))	;
			        	List<WorkFlowInstance> result = criteria.list();
			        	if  (result.size()>0)
			        		return result.get(0);
			        	else
			        		return null;
			        }   
			      }   
			    );  
  }
	
	public WorkFlowInstance findInstance(final Form form,final WorkFlow workFlow)
	{
		return (WorkFlowInstance )getHibernateTemplate().execute(   
			      new HibernateCallback() {   
			        @SuppressWarnings("unchecked")
					public Object doInHibernate(Session session) throws HibernateException {   
			        	Criteria criteria =  session.createCriteria(WorkFlowInstance.class);
			        	criteria.add(Restrictions.eq("form", form))
			        				.add(Restrictions.eq("flow", workFlow));	
			        	List<WorkFlowInstance> result = criteria.list();
			        	if  (result.size()>0)
			        		return result.get(0);
			        	else
			        		return null;
			        }   
			      }   
			    );  
	}
	
	public int countFlowInstance(final WorkFlow workflow)
	{
		return (Integer)getHibernateTemplate().execute(   
			      new HibernateCallback() {   
			        public Object doInHibernate(Session session) throws HibernateException {   
			        	Criteria criteria =  session.createCriteria(WorkFlowInstance.class);
			        	criteria.add(Restrictions.eq("flow", workflow));
			        	criteria.setProjection(Projections.count("id"));
			        	return criteria.uniqueResult();
			        }   
			      }   
			    );  
	}

	@Override
	public WorkFlowInstance findByFormName(final String name) {
		Criteria criteria=this.getSession().createCriteria(WorkFlowInstance.class);
		criteria.createAlias("form", "fm");
		criteria.add(Restrictions.eq("fm.ename", name));
		List result=criteria.list();
		if (result.size()>0) {
			return (WorkFlowInstance) criteria.list().get(0);
		}else{
 		return null;
	}
}

	@Override
	public List<WorkFlowInstance> getAllWorkFlowInstance() {
		Criteria criteria=this.getSession().createCriteria(WorkFlowInstance.class);
		return criteria.list();
	}
}
